using System;
using System.Collections.Generic;
using System.Xml;
using System.IO;
using UnityEngine;

public class XmlNode {
  public string Name { get; private set; }
  private Dictionary<string, string> _attributes;
  private Dictionary<string, List<XmlNode>> _children;
  public string InnerText { get; private set; }

  public Dictionary<string, string> Attributes {
    get {
      if (_attributes == null)
        _attributes = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
      return _attributes;
    }
  }

  public Dictionary<string, List<XmlNode>> Children {
    get {
      if (_children == null)
        _children = new Dictionary<string, List<XmlNode>>(StringComparer.OrdinalIgnoreCase);
      return _children;
    }
  }

  public XmlNode(string name) {
    Name = name;
    // 延迟初始化 Attributes 和 Children
  }

  public XmlNode() {
    Name = null;
    // 保持 null 状态直到首次访问
  }

  public bool IsEmpty { get => Name == null; }

  public void AddAttribute(string key, string value) {
    // 通过属性访问器确保初始化
    Attributes[key] = value;
  }

  public void AddChild(XmlNode child) {
    // 通过属性访问器确保初始化
    if (!Children.ContainsKey(child.Name)) {
      Children[child.Name] = new List<XmlNode>();
    }
    Children[child.Name].Add(child);
  }

  public void SetInnerText(string text) {
    InnerText = text;
  }

  private static readonly XmlNode NULL_ITEM = new();

  public XmlNode Get(string name) {
    if (_children != null && _children.ContainsKey(name) && _children[name].Count > 0) {
      return _children[name][0];
    }
    return NULL_ITEM;
  }

  public List<XmlNode> GetNodes(string name) {
    if (_children != null && _children.ContainsKey(name) && _children[name].Count > 0) {
      return _children[name];
    }
    return null;
  }

  public string GetStr(string key, string defaultValue = null) {
    // 检查属性是否存在（不触发初始化）
    if (_attributes != null && _attributes.ContainsKey(key)) {
      return _attributes[key];
    }

    // 检查子节点是否存在（不触发初始化）
    if (_children != null && _children.ContainsKey(key) && _children[key].Count > 0) {
      return _children[key][0].InnerText;
    }

    return defaultValue;
  }

  public int GetInt(string key, int defaultValue = 0) {
    string value = GetStr(key);
    if (string.IsNullOrEmpty(value)) return defaultValue;

    return int.TryParse(value, out int result) ? result : defaultValue;
  }

  public long GetLong(string key, long defaultValue = 0) {
    string value = GetStr(key);
    if (string.IsNullOrEmpty(value)) return defaultValue;

    return long.TryParse(value, out long result) ? result : defaultValue;
  }

  public bool GetBool(string key, bool defaultValue = false) {
    string value = GetStr(key);
    if (string.IsNullOrEmpty(value)) return defaultValue;

    return bool.TryParse(value, out bool result) ? result : defaultValue;
  }

  public Vector3Int GetVector3Int(string key) {
    string value = GetStr(key);
    if (string.IsNullOrEmpty(value)) return Vector3Int.zero;
    return ParseVector3Int(value);
  }

  public Vector2Int GetVector2Int(string key) {
    string value = GetStr(key);
    if (string.IsNullOrEmpty(value)) return Vector2Int.zero;
    return ParseVector2Int(value);
  }

  public static Vector3Int ParseVector3Int(string str) {
    string[] components = str.Split(',');

    if (components.Length == 3 &&
        int.TryParse(components[0], out int x) &&
        int.TryParse(components[1], out int y) &&
        int.TryParse(components[2], out int z)) {
      return new Vector3Int(x, y, z);
    } else {
      return Vector3Int.zero;
    }
  }

  public static Vector2Int ParseVector2Int(string str) {
    string[] components = str.Split(',');

    if (components.Length == 2 &&
        int.TryParse(components[0], out int x) &&
        int.TryParse(components[1], out int y)) {
      return new Vector2Int(x, y);
    } else {
      return Vector2Int.zero;
    }
  }

  public float GetFloat(string key, float defaultValue = 0f) {
    string value = GetStr(key);
    if (string.IsNullOrEmpty(value)) return defaultValue;

    float result;
    return float.TryParse(value, out result) ? result : defaultValue;
  }

  public bool Has(string key) {
    return (_attributes != null && _attributes.ContainsKey(key)) ||
           (_children != null && _children.ContainsKey(key) && _children[key].Count > 0);
  }

  public bool HasAttributes => _attributes != null && _attributes.Count > 0;
  public bool HasChildren => _children != null && _children.Count > 0;
}

public class XmlReader {
  public XmlNode Root { get; private set; }

  /// <summary>
  /// 通过XML字符串内容初始化
  /// </summary>
  /// <param name="xmlContent">完整的XML字符串</param>
  public XmlReader(string xmlContent) {
    if (string.IsNullOrWhiteSpace(xmlContent)) {
      Debuger.LogError("XML content cannot be null or empty");
      Root = new XmlNode();
      return;
    }

    try {
      XmlDocument doc = new XmlDocument();
      doc.LoadXml(xmlContent);
      Root = ParseNode(doc.DocumentElement);
    } catch (XmlException ex) {
      Debuger.LogError($"Failed to parse XML: {ex.Message}");
      Root = new XmlNode();
    }
  }

  /// <summary>
  /// 递归解析XML节点
  /// </summary>
  private XmlNode ParseNode(XmlElement element) {
    XmlNode node = new XmlNode(element.Name);

    // 处理属性
    foreach (XmlAttribute attr in element.Attributes) {
      node.AddAttribute(attr.Name, attr.Value);
    }

    // 处理子节点
    foreach (System.Xml.XmlNode child in element.ChildNodes) {
      if (child is XmlElement) {
        node.AddChild(ParseNode((XmlElement)child));
      } else if (child is XmlText) {
        node.SetInnerText(child.Value?.Trim());
      }
      // 忽略注释、CDATA等其他节点类型
    }

    return node;
  }
}